<template>
  <header class="header">
    <el-input style="width: 100%" size="default" v-model="searchText" placeholder="搜索名称">
      <template #prefix>
        <ElIcon>
          <Search />
        </ElIcon>
      </template>
    </el-input>
    <el-button-group style="display: flex">
      <el-button type="primary" icon="Plus" plain @click="addMenu">新 增</el-button>
    </el-button-group>
  </header>
  <main class="main">
    <el-tree
      v-loading="loading"
      :data="menuList"
      :filter-node-method="filterNode"
      highlight-current
      :props="defaultProps"
      node-key="name"
      ref="treeRef"
      @node-click="nodeClick"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node" @mouseenter="mouseNodeKey = data.name" @mouseleave="mouseNodeKey = ''">
          <article style="display: flex; gap: 5px; justify-content: center">
            <ElIcon size="16">
              <component :is="data.meta.icon" />
            </ElIcon>
            <span style="margin-left: 5px; font-size: 16px; line-height: 16px">{{ data.meta.title }}</span>
          </article>
          <article v-if="mouseNodeKey === data.name || currentNodeKey === data.name" style="margin-right: 5px">
            <el-link type="primary" v-if="data.meta.parentId === 0" @click.stop="addChildMenu(data)">新增</el-link>
            <el-popconfirm confirm-button-text="确定" link cancel-button-text="取消" @confirm="deleteMenu(data)" title="删除该菜单？">
              <template #reference>
                <el-link type="danger" style="margin-left: 5px">删除</el-link>
              </template>
            </el-popconfirm>
          </article>
        </span>
      </template>
    </el-tree>
  </main>
</template>

<script name="menuTree" setup>
  import router from '@/router';
  import { useMenuApi } from '@/api/menu-api.js';
  import { RStatus } from '@/common/comstants.js';
  import { useMenuStore } from '@/store/menu-store.js';
  import { DataUtil } from '@/utils/data-util.js';
  import { updateRoute } from '@/utils/router-update-util.js';

  const treeRef = ref();
  const defaultProps = {
    children: 'children',
  };
  const _emit = defineEmits(['nodeClick', 'addChildMenu', 'addMenu']);
  const _props = defineProps({
    menuInfo: {
      type: Object,
      default: () => ({}),
    },
  });

  let menuList = ref([]);
  let mouseNodeKey = ref('');
  let currentNodeKey = ref('');
  let searchText = ref('');
  let loading = ref(false);

  onMounted(() => {
    getMenuList();
  });

  watch(searchText, (val) => {
    treeRef.value.filter(val);
  });

  /** 获取菜单列表 */
  const getMenuList = async () => {
    loading.value = true;
    try {
      const res = await useMenuApi().getList();
      if (res.status === RStatus.SUCCESS) {
        menuList.value = updateRoute(res.data);
      }
    } finally {
      loading.value = false;
    }
  };

  const filterNode = (value, data) => {
    if (!value) return true;
    return data.meta.title.includes(value);
  };

  const addMenu = () => {
    _emit('addMenu');
  };

  /**
   * 点击左侧节点赋值
   * @param data 节点菜单
   */
  const nodeClick = (data) => {
    activeNode(data);
    _emit('nodeClick', DataUtil.deepCopy(data.meta));
  };

  /**
   * 新增子菜单
   * @param data 节点数据
   */
  const addChildMenu = (data) => {
    activeNode(data);
    _emit('addChildMenu', data.meta.menuId);
  };

  const activeNode = (data) => {
    currentNodeKey.value = data.name;
    treeRef.value.setCurrentKey(data.name);
  };

  /**
   * 删除菜单
   * @param data 节点数据
   */
  const deleteMenu = (data) => {
    useMenuApi()
      .delete(data.meta.menuId)
      .then((res) => {
        if (res.status === RStatus.SUCCESS) {
          ElMessage.success(res.data);
          useMenuStore().fetchRoutes(router);
        }
      });
  };

  defineExpose({
    getMenuList,
  });
</script>

<style lang="scss" scoped>
  .menu {
    background-color: #f9fafb;
    min-width: 320px;
    max-width: 420px;
    border-right: 1px solid rgba(0, 0, 0, 0.06);

    .header {
      display: flex;
      gap: 12px;
      align-items: center;
      background: linear-gradient(to right, #f4f7f9, #f9fafb);
      padding: 16px;
      border-bottom: 1px solid rgba(0, 0, 0, 0.06);

      .el-input {
        flex: 1;

        .el-input__wrapper {
          background-color: #ffffff;
          border: 1px solid #e0e6ed;
          border-radius: 8px;
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
          transition: all 0.3s ease;

          &:hover {
            border-color: #4a90e2;
            box-shadow: 0 0 8px rgba(74, 144, 226, 0.2);
          }
        }
      }

      .el-button-group {
        .el-button {
          transition: all 0.3s ease;
          &:hover {
            transform: translateY(-2px);
          }
        }
      }
    }

    .main {
      padding: 16px;

      .el-tree {
        background-color: transparent;

        .el-tree-node {
          &.is-current {
            > .el-tree-node__content {
              background-color: rgba(74, 144, 226, 0.1);
            }
          }
        }
      }
    }
  }

  .custom-tree-node {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12px;
    justify-content: space-between;
    transition: all 0.3s ease;
    border-radius: 8px;
    padding-right: 15px;

    article {
      display: flex;
      align-items: center;
      gap: 10px;

      .el-icon {
        color: #4a90e2;
        transition: transform 0.3s ease;
      }

      &:first-child:hover .el-icon {
        transform: scale(1.1);
      }
    }
  }

  :deep(.el-tree-node__content) {
    height: 48px;
    transition: all 0.3s ease;
    border-radius: 8px;
    margin: 4px 0;

    &:hover {
      background-color: rgba(74, 144, 226, 0.1);
    }
  }

  .header {
    .el-input {
      .el-input__wrapper {
        box-shadow: none;
        border: 1px solid #e4e7ed;
        transition: all 0.3s ease;

        &:hover,
        &:focus {
          border-color: #4a90e2;
          box-shadow: 0 0 0 1px #4a90e2;
        }
      }
    }

    .el-button-group {
      .el-button {
        transition: all 0.3s ease;

        &:hover {
          transform: translateY(-2px);
          box-shadow: 0 2px 8px rgba(74, 144, 226, 0.2);
        }
      }
    }
  }

  @media screen and (max-width: 768px) {
    .menu {
      width: 100%;
      max-width: 100%;
      min-width: auto;
    }
  }
</style>
@/store/menu@/store/menu.js@/store/menu-store.js@/api/menu-api@/store/menu-store.js@/utils/data-util@/utils/router-update-util